import SchemaMeta from './schema-meta';
import type { PackagesParserProps, PackagesLevel, Package, PackagesParserConstructorProps } from '../types';

export default class PackagesParser extends SchemaMeta implements PackagesParserProps {
  private packages: Record<PackagesLevel, Package[]>;
  constructor(props: PackagesParserConstructorProps) {
    super(props);
    /**
     * 维护资源优先级
     */
    this.packages = {
      // 环境基础包 例如 react
      1: [{ exportName: 'React', packageName: 'react' }],
      // 第三方包 例如 antd
      2: [],
      // 组件库的包 例如 @forestar/xx
      3: [],
      // 本项目内组件、工具 例如 @/component/xx
      4: [],
      // 当前组件的工具 例如 ./xx
      5: [],
      // 样式
      6: [],
    };
  }

  toString() {
    const packages = [
      ...this.packages[1],
      ...this.packages[2],
      ...this.packages[3],
      ...this.packages[4],
      ...this.packages[5],
      ...this.packages[6],
    ].filter((v) => v.exportName || v.subName?.length);
    return packages.map((item) => {
      const { exportName, destructuring, subName, packageName } = item;
      const subNameStr = destructuring && subName?.length ? `${exportName ? ', ' : ''}{${subName.join(', ')}}` : '';
      return `import ${exportName || ''}${subNameStr} from '${packageName}'`;
    });
  }
  setPackages(level: PackagesLevel, packageItem: Package) {
    if (Array.isArray(this.packages[level])) {
      this.packages[level].push(packageItem);
    }
  }
  getPackages(): Package[] {
    return [
      ...this.packages[1],
      ...this.packages[2],
      ...this.packages[3],
      ...this.packages[4],
      ...this.packages[5],
      ...this.packages[6],
    ].filter((v) => v.exportName || v.subName?.length);
  }
  setEnvironmentPackages(packageItem: Package) {
    let lock = false;
    this.packages[1] = this.packages[1].map((pkg) => {
      if (pkg.packageName === packageItem.packageName) {
        lock = true;
        pkg = {
          ...pkg,
          ...packageItem,
          subName: [...new Set([...(pkg.subName || []), ...(packageItem.subName || [])])].filter(Boolean),
        };
        pkg.destructuring = !!pkg.subName!.length;
      }
      return pkg;
    });
    if (!lock) {
      this.packages[1].push(packageItem);
    }
  }
}
